using System;
using System.Collections;
using System.Collections.ObjectModel;
using System.IO;
using System.Reflection;
using BGM.Sensors.MeasuringDevice;
using BGM.Application.View;
namespace BloodGlucoseManagerApplication
{
    /// <summary>
    /// Summary description for PlugInManager.
    /// </summary>
    public class PlugInManager
    {
        Collection<IDataPresenter> viewPlugins = new Collection<IDataPresenter>();

        public Collection<IDataPresenter> ViewPlugins
        {
            get { return viewPlugins; }
            set { viewPlugins = value; }
        }
        Collection<IMeasuringDevice> measurmentsPlugins = new Collection<IMeasuringDevice>();

        public Collection<IMeasuringDevice> MeasurmentsPlugins
        {
            get { return measurmentsPlugins; }
            set { measurmentsPlugins = value; }
        }

        string plugInDirPath;
        Collection<object> plugInFactories = new Collection<object>();

        public Collection<object> PlugInFactories
        {
            get { return plugInFactories; }
            set { plugInFactories = value; }
        }
        ArrayList plugIns = new ArrayList();

        public ArrayList PlugIns
        {
            get { return plugIns; }
            set { plugIns = value; }
        }

        public PlugInManager()
        {
            // Find path to plug-ins, and create directory if it doesn't exist
            //plugInDirPath = Environment.CurrentDirectory + @"\Plug-ins";
            // CurrentDirectory may change, so this is a better algorithm
            plugInDirPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Plugin");
            //Trace.WriteLine("plugInDirPath = " + plugInDirPath);
            DirectoryInfo plugInDir = new DirectoryInfo(plugInDirPath);
           

            try
            {
                if (!plugInDir.Exists)
                {
                    Directory.CreateDirectory(plugInDir.FullName);
                    //plugInDir.Create();
                }
            }
            catch (Exception ex)
            {
                //DialogResult res = MessageBox.Show("Unable to create Plug-ins directory. Error messge: " + ex.Message, "My Extensible Application", MessageBoxButtons.AbortRetryIgnore);
                //if (res == DialogResult.Abort)
                //    Application.Exit();
            }
        }


        public void LoadAssemblies()
        {
            DirectoryInfo plugInDir = new DirectoryInfo(plugInDirPath);
            FileInfo[] assemblies = plugInDir.GetFiles("*.dll");

            foreach (FileInfo fi in assemblies)
            {
                //Trace.WriteLine("Found: " + fi.Name);
                //Trace.WriteLine(fi.FullName);
                // Load the assembly
                Assembly assembly = Assembly.LoadFrom(fi.FullName);
                // Find class factory type?
                object factory;
                Type factoryType = typeof(IMeasuringDevice);
                Type factoryType2 = typeof(IDataPresenter);
                //Trace.WriteLine("factoryType: " + factoryType.FullName);
                Type[] types = assembly.GetTypes();
                foreach (Type t in types)
                {
                    try
                    {
                        //Trace.WriteLine("Tested Type: " + t.FullName);
                        if (factoryType.IsAssignableFrom(t) && !t.IsInterface)
                        {
                            //Trace.WriteLine("Found classfactory: " + t.FullName);
                            //factory = (object)Activator.CreateInstance(t);
                            measurmentsPlugins.Add(Activator.CreateInstance(t) as IMeasuringDevice);
                            break; // match found and only one factory in each plug-in so move on

                        }
                        else if (factoryType2.IsAssignableFrom(t) && !t.IsInterface)
                        {
                            viewPlugins.Add(Activator.CreateInstance(t) as IDataPresenter);
                            break;
                        }
                    }
                    catch (Exception ex)
                    {
                        //DialogResult res = MessageBox.Show("Internale error in loaded Plug-in: " +
                        //    assembly.FullName + " Error messge: " + ex.Message, "My Extensible Application", MessageBoxButtons.AbortRetryIgnore);
                        //if (res == DialogResult.Abort)
                        //    Application.Exit();
                    }
                }
            }
        }

        //public void InstantiatePlugInObjects()
        //{
        //    IPlugin plugin;

        //    foreach (IPlugin factory in plugInFactories)
        //    {
        //        plugin = factory.CreateObject();
        //        plugin.Initialize(util);
        //        plugIns.Add(plugin);
        //    }
        //}

        //public void CallPlugInObjects()
        //{
        //    foreach (IReportPlugIn plugin in plugIns)
        //    {
        //        Trace.WriteLine("Calling Run in " + plugin.ToString());
        //        plugin.Execute();
        //    }
        //}

        public void TearDownPlugInObjects()
        {
            //foreach (IPlugin plugin in PlugInFactories)
            //{
            //    plugin.Dispose();
            //}
        }

    }
}
